package com.atguigu.tingshu.common.threadpool;

import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

@Configuration
@EnableConfigurationProperties(ThreadPoolConfigProperties.class)
public class ThreadPoolAutoConfiguration {

    private static final org.slf4j.Logger log = LoggerFactory.getLogger(ThreadPoolAutoConfiguration.class);
    @Value("${spring.application.name}")
    private String appName;

    /**
     * 自定义线程池
     */
    @Bean
    public ThreadPoolExecutor threadPoolExecutor(ThreadPoolConfigProperties threadPoolConfigProperties) {
        int corePoolSize = threadPoolConfigProperties.getCorePoolSize();
        int maximumPoolSize = threadPoolConfigProperties.getMaxPoolSize();
        long keepAliveTime = threadPoolConfigProperties.getKeepAliveTime();
        TimeUnit unit = TimeUnit.SECONDS;
        BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>(threadPoolConfigProperties.getQueueSize());

        AtomicInteger atomicInteger = new AtomicInteger(0);
        ThreadFactory threadFactory = r -> {
            Thread thread = new Thread(r);
            thread.setName("codingyz-thread-【" + appName + "】" + atomicInteger.getAndIncrement());
            return thread;
        };
        RejectedExecutionHandler rejectedExecutionHandler = new RejectedExecutionHandler() {
            @Override
            public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
                log.error("任务被拒绝！{}", r.toString());
            }
        };
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                corePoolSize,
                maximumPoolSize,
                keepAliveTime,
                unit,
                workQueue,
                threadFactory,
                rejectedExecutionHandler
        );
        return threadPoolExecutor;
    }
}
